from code_builder.templet import read_temp_file
from code_builder.conf import read_conf
from code_builder.tools import utils, create_file_name, code_builder


def create_java_file(data, target_path, table_name):
    if read_conf.getConfig("file", "create_java_dao") == "True":
        create_dao_file(target_path, table_name)
    if read_conf.getConfig("file", "create_java_service") == "True":
        create_service_file(target_path, table_name)
        create_serviceimpl_file(target_path, table_name)
    if read_conf.getConfig("file", "create_java_controller") == "True":
        create_controller_file(target_path, table_name, data)
    if read_conf.getConfig("file", "create_java_entity") == "True":
        create_entity_file(target_path, table_name, data)
    if read_conf.getConfig("file", "create_java_xml") == "True":
        create_mapper_file(target_path, table_name, data)


def create_dao_file(target_path, table_name):
    data = get_dao_data(table_name)
    name = create_file_name.dao_name(table_name)
    if utils.create_file(target_path, name, data):
        utils.print_create_success(name)


def get_dao_data(table_name):
    temp = read_temp_file.read_java_dao()
    base_package = read_conf.getConfig("java", "base_package")
    cap_table_name = utils.to_cap_camel_case(table_name)
    low_table_name = utils.to_low_camel_case(table_name)
    b = code_builder.pre_fmt(temp)
    c = b.format(base_package=base_package, cap_table_name=cap_table_name, low_table_name=low_table_name)
    return code_builder.after_fmt(c)


def create_service_file(target_path, table_name):
    data = get_service_data(table_name)
    name = create_file_name.service_name(table_name)
    if utils.create_file(target_path, name, data):
        utils.print_create_success(name)


def get_service_data(table_name):
    temp = read_temp_file.read_java_service()
    base_package = read_conf.getConfig("java", "base_package")
    cap_table_name = utils.to_cap_camel_case(table_name)
    low_table_name = utils.to_low_camel_case(table_name)
    b = code_builder.pre_fmt(temp)
    c = b.format(base_package=base_package, cap_table_name=cap_table_name, low_table_name=low_table_name)
    return code_builder.after_fmt(c)


def create_serviceimpl_file(target_path, table_name):
    data = get_serviceimpl_data(table_name)
    name = create_file_name.service_impl_name(table_name)
    if utils.create_file(target_path, name, data):
        utils.print_create_success(name)


def get_serviceimpl_data(table_name):
    temp = read_temp_file.read_java_service_impl()
    base_package = read_conf.getConfig("java", "base_package")
    cap_table_name = utils.to_cap_camel_case(table_name)
    low_table_name = utils.to_low_camel_case(table_name)
    b = code_builder.pre_fmt(temp)
    c = b.format(base_package=base_package, cap_table_name=cap_table_name, low_table_name=low_table_name)
    return code_builder.after_fmt(c)


def create_controller_file(target_path, table_name, data):
    data = get_controller_data(table_name, data)
    name = create_file_name.controller_name(table_name)
    if utils.create_file(target_path, name, data):
        utils.print_create_success(name)


def get_controller_data(table_name, data):
    temp = read_temp_file.read_java_controller()
    base_package = read_conf.getConfig("java", "base_package")
    cap_table_name = utils.to_cap_camel_case(table_name)
    low_table_name = utils.to_low_camel_case(table_name)
    req_code = get_req_code(table_name, data)
    b = code_builder.pre_fmt(temp)
    c = b.format(base_package=base_package, cap_table_name=cap_table_name, low_table_name=low_table_name,
                 req_code=req_code)
    return code_builder.after_fmt(c)


def get_req_code(table_name, data):
    result = ""
    ob_name = utils.to_low_camel_case(table_name)
    for i in range(1, len(data) - 3):
        fmt = ""
        if data[i]['field_type'] == "NUMBER":
            if data[i]['field_len'] == 15.0:
                fmt = "{0}.set{1}(new BigDecimal(request.getParameter(\"{2}\")));"
            else:
                fmt = "{0}.set{1}(Integer.parseInt(request.getParameter(\"{2}\")));"
        else:
            fmt = "{0}.set{1}(request.getParameter(\"{2}\"));"
        result += fmt.format(ob_name, utils.to_cap_camel_case(data[i]['field_code']),
                             utils.to_low_camel_case(data[i]['field_code']))
    return result


def create_entity_file(target_path, table_name, data):
    data = get_entity_data(table_name, data)
    name = create_file_name.entity_name(table_name)
    if utils.create_file(target_path, name, data):
        utils.print_create_success(name)


def get_entity_data(table_name, data):
    temp = read_temp_file.read_java_entity()
    base_package = read_conf.getConfig("java", "base_package")
    cap_table_name = utils.to_cap_camel_case(table_name)
    attr_code = get_attr_code(data)
    fun_code = get_fun_code(data)
    b = code_builder.pre_fmt(temp)
    c = b.format(base_package=base_package, cap_table_name=cap_table_name, attr_code=attr_code, fun_code=fun_code)
    return code_builder.after_fmt(c)


def get_attr_code(data):
    result = ""
    for i in range(0, len(data)):
        fmt = "    private {type} {value_name};\n"
        field_code = utils.to_low_camel_case(data[i]['field_code'])
        field_type = data[i]['field_type']
        if field_type == "VARCHAR2" or field_type == "CHAR" or field_type == "NVARCHAR2":
            result += fmt.format(type="String", value_name=field_code)
        elif field_type == "NUMBER":
            if data[i]['field_len'] == 15.0:
                result += fmt.format(type="BigDecimal", value_name=field_code)
            else:
                result += fmt.format(type="int", value_name=field_code)
        elif field_type == "DATE":
            if field_code == "createTime" or field_code == "modifiedTime":
                result += fmt.format(type="Date", value_name=field_code)
            else:
                result += fmt.format(type="String", value_name=field_code)
    return result


def get_fun_code(data):
    result = ""
    for i in range(0, len(data)):
        fmt = """\n    public {field_type} get{cap_field_code}() _{_
        return {low_field_code};
    _}_\n

    public void set{cap_field_code}({field_type} {low_field_code}) _{_
        this.{low_field_code} = {field_code};
    _}_"""
        fmt = fmt.replace("_{_", "_1")
        fmt = fmt.replace("_}_", "_2")
        field_code = data[i]['field_code']
        low_field_code = utils.to_low_camel_case(data[i]['field_code'])
        cap_field_code = utils.to_cap_camel_case(data[i]['field_code'])
        field_type = data[i]['field_type']
        if field_type == "VARCHAR2" or field_type == "CHAR" or field_type == "NVARCHAR2":
            field_type = "String"
            field_code = "{low_field_code} == null ? null : {low_field_code}.trim()".format(
                low_field_code=low_field_code)
        elif field_type == "NUMBER":
            if data[i]['field_len'] == 15.0:
                field_type = "BigDecimal"
            else:
                field_type = "int"
            field_code = low_field_code
        elif field_type == "DATE":
            if field_code == "CREATE_TIME" or field_code == "MODIFIED_TIME":
                field_type = "Date"
            else:
                field_type = "String"
            field_code = low_field_code
        result += fmt.format(field_type=field_type, cap_field_code=cap_field_code, low_field_code=low_field_code,
                             field_code=field_code)
    return result


def create_mapper_file(target_path, table_name, data):
    data = get_mapper_data(table_name, data)
    name = create_file_name.mapper_name(table_name)
    if utils.create_file(target_path, name, data):
        utils.print_create_success(name)


def get_mapper_data(table_name, data):
    temp = read_temp_file.read_xml_mapper()
    base_package = read_conf.getConfig("java", "base_package")
    cap_table_name = utils.to_cap_camel_case(table_name)
    low_table_name = utils.to_low_camel_case(table_name)
    result_column_list = get_result_column_list(data)
    col_list = get_col_list(data)
    insert_col = get_insert_col_code(data)
    insert_value = get_insert_value_code(data)
    update_col_value = get_update_col_value_code(data)
    b = code_builder.pre_fmt(temp)
    c = b.format(base_package=base_package, cap_table_name=cap_table_name, table_name=table_name, insert_col=insert_col,
                 insert_value=insert_value, update_col_value=update_col_value, low_table_name=low_table_name,
                 result_column_list=result_column_list, col_list=col_list)
    return code_builder.after_fmt(c)


def get_result_column_list(data):
    result = ""
    for i in range(len(data)):
        if i == 0:
            continue
        one = data[i]
        field_code = one['field_code']
        low_table_name = utils.to_low_camel_case(field_code)
        field_type = ""
        if one['field_type'] == "NUMBER":
            field_type = "DECIMAL"
        elif one['field_type'] == "VARCHAR2":
            field_type = "VARCHAR"
        elif one['field_type'] == "NVARCHAR2":
            field_type = "NVARCHAR"
        elif one['field_type'] == "DATE":
            field_type = "TIMESTAMP"
        elif one['field_type'] == "CHAR":
            field_type = "CHAR"
        result += "<result column=\"{field_code}\" property=\"{low_table_name}\" jdbcType=\"{field_type}\" />\n".format(
            field_code=field_code,
            low_table_name=low_table_name,
            field_type=field_type)
    return result


def get_col_list(data):
    result = ""
    for i in range(len(data)):
        one = data[i]
        result += one['field_code']
        if i != len(data) - 1:
            result += ","
    return result


def get_insert_col_code(data):
    result = ""
    for i in range(len(data)):
        if i == 0:
            continue
        one = data[i]
        field_code = one['field_code']
        field_restrain = one['field_restrain']
        low_table_name = utils.to_low_camel_case(field_code)
        if field_restrain == "M":
            result += "\n		{field_code}".format(field_code=field_code)
            if i != len(data) - 1:
                result += ","
        else:
            result += """\n		<if test="{low_table_name} != null">
			{field_code},
		</if>""".format(low_table_name=low_table_name, field_code=field_code)
    return result


def get_insert_value_code(data):
    result = ""
    for i in range(len(data)):
        if i == 0:
            continue
        one = data[i]
        field_code = one['field_code']
        field_restrain = one['field_restrain']
        low_table_name = utils.to_low_camel_case(field_code)
        value = builder_update_insert_value(one)
        if i == len(data):
            value += ","
        if field_code == "STATUS":
            result += "\n		1,"
        elif field_code == "CREATE_TIME":
            result += "\n		sysdate,"
        elif field_code == "MODIFIED_TIME":
            result += "\n		sysdate"
        else:
            if field_restrain == "M":
                result += "\n		{value}".format(value=value)
            else:
                result += """\n		<if test="{low_table_name} != null">
                {value}
            </if>""".format(low_table_name=low_table_name, value=value)
    return result


def get_update_col_value_code(data):
    result = ""
    for i in range(len(data)):
        if i == 0:
            continue
        one = data[i]
        field_code = one['field_code']
        if field_code != "STATUS" and field_code != "CREATE_TIME":
            if field_code == "MODIFIED_TIME":
                result += "{field_code} = sysdate".format(field_code=field_code)
            else:
                low_table_name = utils.to_low_camel_case(field_code)
                value = builder_update_insert_value(one)
                value += ","
                result += """			<if test="{low_table_name} != null">
                        {field_code} =
                        {value}
                    </if>\n""".format(low_table_name=low_table_name, field_code=field_code, value=value)
    return result


def builder_update_insert_value(one):
    field_code = one['field_code']
    low_table_name = utils.to_low_camel_case(field_code)
    field_type = ""
    if one['field_type'] == "NUMBER":
        field_type = "DECIMAL"
    elif one['field_type'] == "VARCHAR2":
        field_type = "VARCHAR"
    elif one['field_type'] == "NVARCHAR2":
        field_type = "NVARCHAR"
    elif one['field_type'] == "DATE":
        field_type = "TIMESTAMP"
    elif one['field_type'] == "CHAR":
        field_type = "CHAR"
    if one['field_type'] == "DATE":
        value = "to_date(#{" + low_table_name + ",jdbcType=" + field_type + "},'yyyy-mm-dd'),"
    else:
        value = "#{" + low_table_name + ",jdbcType=" + field_type + "},"
    return value
